package com.example;

import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import java.io.IOException;
import java.io.InputStream;
import java.net.InetSocketAddress;

@SpringBootApplication
public class JschMain {
    static final Logger LOG = LoggerFactory.getLogger(JschMain.class);

    private static Integer Port = 8020;
    private static Integer Timeout = 30000;

//    private static String Host = "hadoop01";
//    private static String User = "vagrant";

//    private static String Host = "vm-16-13-centos";
//    private static String User = "muyesancai";

    private static String Host = "hadoop04";
    private static String User = "vagrant";

    public static void main(String[] args) {
        System.out.println("Hello world!");
        JschMain jschMain = new JschMain();

        String keyFile = "data/hadoop04/id_rsa";
        InetSocketAddress inetSocketAddress = new InetSocketAddress(Host, Port);

        boolean tryFence = jschMain.tryFence(inetSocketAddress, keyFile);
        LOG.info("tryFence: " + tryFence);

    }

    public boolean tryFence(InetSocketAddress serviceAddr, String keyFile) {
        String host = serviceAddr.getHostName();

        Session session;
        JSchException e;
        try {
            session = this.createSession(host, keyFile);
        } catch (JSchException var15) {
            e = var15;
            LOG.warn("Unable to create SSH session", e);
            return false;
        }

        LOG.info("Connecting to " + host + "...");

        try {
            session.connect(Timeout);
        } catch (JSchException var14) {
            e = var14;
            LOG.warn("Unable to connect to " + host + " as user vagrant", e);
            return false;
        }

        LOG.info("Connected to " + host);

        boolean var8;
        try {
            boolean var18 = this.doFence(session, serviceAddr);
            return var18;
        } catch (JSchException var16) {
            e = var16;
            LOG.warn("Unable to achieve fencing on remote host", e);
            var8 = false;
        } finally {
            session.disconnect();
        }

        return var8;
    }

    private Session createSession(String host, String keyFile) throws JSchException {
        JSch jsch = new JSch();
        jsch.addIdentity(keyFile);
        Session session = jsch.getSession(User, host, 22);
        session.setConfig("StrictHostKeyChecking", "no");
        return session;
    }

    private boolean doFence(Session session, InetSocketAddress serviceAddr) throws JSchException {
        int port = serviceAddr.getPort();

        try {
            LOG.info("Looking for process running on port " + port);
            int rc = this.execCommand(session, "PATH=$PATH:/sbin:/usr/sbin fuser -v -k -n tcp " + port);
            if (rc == 0) {
                LOG.info("Successfully killed process that was listening on port " + port);
                return true;
            } else if (rc == 1) {
                LOG.info("Indeterminate response from trying to kill service. Verifying whether it is running using nc...");
                rc = this.execCommand(session, "nc -z " + serviceAddr.getHostName() + " " + serviceAddr.getPort());
                if (rc == 0) {
                    LOG.warn("Unable to fence - it is running but we cannot kill it");
                    return false;
                } else {
                    LOG.info("Verified that the service is down.");
                    return true;
                }
            } else {
                LOG.info("rc: " + rc);
                return rc == 0;
            }
        } catch (InterruptedException var5) {
            InterruptedException e = var5;
            LOG.warn("Interrupted while trying to fence via ssh", e);
            return false;
        } catch (IOException var6) {
            IOException e = var6;
            LOG.warn("Unknown failure while trying to fence via ssh", e);
            return false;
        }
    }

    private int execCommand(Session session, String cmd) throws JSchException, InterruptedException, IOException {
        LOG.info("Running cmd: " + cmd);
        ChannelExec exec = null;

        int var6;
        try {
            exec = (ChannelExec)session.openChannel("exec");
            exec.setCommand(cmd);
            exec.setInputStream((InputStream)null);
            exec.connect();
            var6 = exec.getExitStatus();
        } finally {
            cleanup(exec);
        }

        return var6;
    }

    private static void cleanup(ChannelExec exec) {
        if (exec != null) {
            try {
                exec.disconnect();
            } catch (Throwable var2) {
                Throwable t = var2;
                LOG.info("Couldn't disconnect ssh channel. \n" + t);
            }
        }

    }
}